<template>
  <Form
    :model="formState"
    ref="formRef"
    class="md:flex-row w-full flex-wrap"
    layout="inline"
    v-model="initData"
    v-bind="formItemLayout"
  >
    <div class="md:flex w-full md:justify-between items-center">
      <div class="md:flex md:justify-start">
        <Col :span="7">
          <FormItem name="timeRange" label="时间范围">
            <RangePicker
              v-model:value="timeRange"
              :format="format"
              :show-time="showTimeRef"
              :ranges="timeRangeOptions"
              :disabledDate="disabledDate"
              @change="onTimeRangeChange"
              @calendarChange="onCalendarChange"
              @openChange="onOpenChange"
              style="width: 350px"
            ></RangePicker>
          </FormItem>
        </Col>
        <FormItem name="service" label="当前服务">
          <Select
            v-model:value="service"
            placeholder="请选择服务"
            :options="serviceOptions"
            :allowClear="true"
            :disabled="serviceDisabled"
            @change="onServiceChange"
            style="width: 240px"
          >
          </Select>
        </FormItem>
        <FormItem name="endpoint" label="当前端点">
          <Select
            v-model:value="endpoint"
            placeholder="请选择端点"
            :options="endpointOptions"
            :allowClear="true"
            :disabled="endpointDisabled"
            style="width: 240px"
          >
          </Select>
        </FormItem>
        <FormItem name="instance" label="当前实例">
          <Select
            v-model:value="instance"
            placeholder="请选择实例"
            :options="instanceOptions"
            :allowClear="true"
            :disabled="instanceDisabled"
            style="width: 340px"
          >
          </Select>
        </FormItem>
      </div>
      <FormItem>
        <div class="md:flex md:justify-end">
          <Button type="primary" shape="circle" @click="onSubmit">
            <template #icon>
              <SearchOutlined />
            </template>
          </Button>
          <Button style="margin-left: 5px" shape="circle" @click="resetForm">
            <template #icon>
              <RedoOutlined />
            </template>
          </Button>
        </div>
      </FormItem>
    </div>
  </Form>
</template>

<script setup lang="ts">
import { computed, reactive, ref } from 'vue';
import moment from 'moment';
import { Button, Col, Form, FormItem, Select, RangePicker } from 'ant-design-vue';
import { SearchOutlined, RedoOutlined } from '@ant-design/icons-vue';
import { getAllEndpoints, getAllInstances, getAllServices } from '/@/api/maintenance-center/skywalking/common/common';
import {
  BaseEntityInfo,
  DurationDto,
  QueryEndpointReq,
  QueryInstanceReq,
  QueryServiceReq,
} from '/@/api/maintenance-center/skywalking/common/model/commonModel';
import dayjs, { Dayjs } from 'dayjs';
const props = defineProps(['initData']);
const initData = computed(() => props.initData);
const emit = defineEmits(['success']);
const formRef = ref();
const showTimeRef = ref(true);
const formState = reactive<Record<string, any>>({});

const formItemLayout = {
  labelCol: { span: 5 },
  wrapperCol: { span: 24 },
};

// Select 组件属性设置
const endpoint = ref();
const endpointOptions = ref<any[]>([]);
const endpointDisabled = ref(true);

const instance = ref();
const instanceOptions = ref<any[]>([]);
const instanceDisabled = ref(true);

const service = ref();
const serviceOptions = ref<any>([]);
const serviceDisabled = ref(true);

type RangeValue = [Dayjs, Dayjs];
const timeRange = ref<RangeValue>();

const timeRangeOptions = {
  最近15分钟: [dayjs().subtract(15, 'minute'), dayjs()] as RangeValue,
  最近30分钟: [dayjs().subtract(30, 'minute'), dayjs()] as RangeValue,
  最近1小时: [dayjs().subtract(1, 'hour'), dayjs()] as RangeValue,
  最近1天: [dayjs().subtract(1, 'day'), dayjs()] as RangeValue,
  最近1周: [dayjs().subtract(1, 'week'), dayjs()] as RangeValue,
  最近1月: [dayjs().subtract(1, 'month'), dayjs()] as RangeValue,
  最近2月: [dayjs().subtract(2, 'month'), dayjs()] as RangeValue,
};
const format = ref<string>('YYYY-MM-DD HH:mm:ss');

const stepFormatMap = {
  SECOND: 'YYYY-MM-DD HHmmss',
  MINUTE: 'YYYY-MM-DD HHmm',
  HOUR: 'YYYY-MM-DD HH',
  DAY: 'YYYY-MM-DD',
  MONTH: 'YYYY-MM',
};

let disabledCurrent: any = null;
let isHandOperated = false;
function onOpenChange(status: boolean) {
  if (status) {
    disabledCurrent = timeRange.value;
  } else {
    // 清空禁用时间段
    disabledCurrent = null;
  }
}

function onCalendarChange(dates: [Dayjs, Dayjs]) {
  // 选择timeRangeOptions
  if (dates && dates[0] && dates[1]) {
    return;
  }
  // 手动选择
  if (dates !== null) {
    isHandOperated = true;
    disabledCurrent = dates;
    return;
  }
}

function disabledDate(current: Dayjs) {
  if (!disabledCurrent) {
    return false;
  }
  // 选择完重新选择时间的场景
  if (disabledCurrent[0] && disabledCurrent[1]) {
    return (
      current && (current > disabledCurrent[0].add(2, 'month') || current < disabledCurrent[1].subtract(2, 'month'))
    );
  }
  if (disabledCurrent[0]) {
    return current && current > disabledCurrent[0].add(2, 'month');
  }
  if (disabledCurrent[1]) {
    return current && current < disabledCurrent[1].subtract(2, 'month');
  }
}

function processDuration(startTime: moment.Moment, endTime: moment.Moment, step: string, durationParam: DurationDto) {
  if (startTime.second() !== endTime.second() && !isHandOperated) {
    step = 'SECOND';
    durationParam.start = startTime.format(stepFormatMap.SECOND);
    durationParam.end = endTime.format(stepFormatMap.SECOND);
  } else if (startTime.minute() !== endTime.minute() && !isHandOperated) {
    step = 'MINUTE';
    durationParam.start = startTime.format(stepFormatMap.MINUTE);
    durationParam.end = endTime.format(stepFormatMap.MINUTE);
  } else if (startTime.hour() !== endTime.hour()) {
    step = 'HOUR';
    durationParam.start = startTime.format(stepFormatMap.HOUR);
    durationParam.end = endTime.format(stepFormatMap.HOUR);
  } else if (startTime.day() !== endTime.day()) {
    step = 'DAY';
    durationParam.start = startTime.format(stepFormatMap.DAY);
    durationParam.end = endTime.format(stepFormatMap.DAY);
  } else {
    step = 'DAY';
    durationParam.start = startTime.format(stepFormatMap.DAY);
    durationParam.end = endTime.format(stepFormatMap.DAY);
  }

  durationParam.step = step;
  return durationParam;
}

let durationParam: DurationDto = {
  start: '',
  end: '',
  step: '',
};

function convertOptions(res: BaseEntityInfo[], sign: number) {
  for (let i = 0; i < res.length; i++) {
    let item = res[i];
    let op = {
      label: item.label,
      value: item.label,
      key: item.key,
    };
    if (sign === 0) {
      serviceOptions.value.push(op);
    } else if (sign === 1) {
      endpointOptions.value.push(op);
    } else if (sign === 2) {
      instanceOptions.value.push(op);
    }
  }
}

const onTimeRangeChange = (data) => {
  if (data !== null && data != undefined && data.length != 0) {
    let startTime = data[0];
    let endTime = data[1];
    let step = '';

    durationParam = processDuration(startTime, endTime, step, durationParam);

    let serviceParams: QueryServiceReq = {
      duration: durationParam,
      keyword: '',
    };

    serviceDisabled.value = false;

    getAllServices(serviceParams).then((res) => {
      serviceOptions.value = [];
      convertOptions(res, 0);
    });
  } else {
    serviceDisabled.value = true;
    endpointDisabled.value = true;
    instanceDisabled.value = true;
    service.value = undefined;
    endpoint.value = undefined;
    instance.value = undefined;
  }
  isHandOperated = false;
};

const onServiceChange = (data, option) => {
  if (data !== null && data != '' && data != undefined) {
    let endpointParams: QueryEndpointReq = {
      serviceId: option.key,
      keyword: '',
      limit: 100,
    };

    let instanceParams: QueryInstanceReq = {
      duration: durationParam,
      serviceId: option.key,
    };

    endpointDisabled.value = false;

    getAllEndpoints(endpointParams).then((res) => {
      endpointOptions.value = [];
      convertOptions(res, 1);
    });

    instanceDisabled.value = false;

    getAllInstances(instanceParams).then((res) => {
      instanceOptions.value = [];
      convertOptions(res, 2);
    });
  } else {
    endpointDisabled.value = true;
    instanceDisabled.value = true;
    endpoint.value = undefined;
    instance.value = undefined;
  }
};

// 提交表单参数
const onSubmit = async () => {
  formRef.value.validate().then(() => {
    let submitParams = {
      duration: durationParam,
      serviceId: service.value,
      endpointId: endpoint.value,
      instanceId: instance.value,
    };
    emit('success', submitParams);
  });
};

// 清空表单参数
const resetForm = () => {
  timeRange.value = [];
  serviceOptions.value = [];
  endpointOptions.value = [];
  instanceOptions.value = [];
  service.value = undefined;
  endpoint.value = undefined;
  instance.value = undefined;
  serviceDisabled.value = true;
  endpointDisabled.value = true;
  instanceDisabled.value = true;
};
</script>
